package space.cloaking.looping;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import space.cloaking.looping.utils.Pools;

/**
 * 一个 LoopQueue 维护一个线程和事件队列，线程消耗事件.
 */
public final class LoopQueue implements ILoopQueue {

    /**
     * 初始状态
     */
    private static final int STATE_INIT = 0;
    /**
     * 启动后的状态
     */
    private static final int STATE_LOOPING = 1;
    /**
     * 正在关闭状态
     */
    private static final int STATE_SHUTTING = 2;
    /**
     * 关闭状态
     */
    private static final int STATE_STOPPED = 3;

    /**
     * 表示 immediate queue
     */
    private static final int QUEUE_IMMEDIATE = 0;
    /**
     * 表示 delay queue
     */
    private static final int QUEUE_DELAY = 1;
    /**
     * 表示 async queue
     */
    private static final int QUEUE_ASYNC = 2;

    /**
     * 表示没有参数的 event
     */
    private static final int EVENT_VOID = 0;
    /**
     * 表示 1 个参数的 event
     */
    private static final int EVENT_1_ARG = 1;
    /**
     * 表示 2 个参数的 event
     */
    private static final int EVENT_2_ARG = 2;
    /**
     * 表示 3 个参数的 event
     */
    private static final int EVENT_3_ARG = 3;
    /**
     * 表示 4 个参数的 event
     */
    private static final int EVENT_4_ARG = 4;
    /**
     * 表示 5 个参数的 event
     */
    private static final int EVENT_5_ARG = 5;

    /**
     * 用去生成默认的线程名
     */
    private static volatile int sThreadIndex = 0;

    /**
     * 线程对应的 LoopQueue
     */
    private static ThreadLocal<LoopQueue> sLocalInstance = new ThreadLocal<>();

    /**
     * 当前状态
     */
    private volatile int mState = STATE_INIT;

    /**
     * 消耗事件的线程
     */
    private final Thread mThread;

    private final BeforeLoopCallback mBeforeLoopCallback;

    private final Object mLock = new Object();

    // The delay queue.
    private Work mDelayQueueHead;
    private Work mDelayQueueTail;

    // The immediate queue.
    private Work mQueueHead;
    private Work mQueueTail;

    /**
     * 本线程使用的 Work 缓存
     */
    private Work mWorkRecycles;

    /**
     * 如果为 true 则本线程正在等待
     */
    private volatile boolean mIsWaiting;

    /**
     * 异步发起的 remove 事件的操作的匹配项
     */
    private volatile Work mRemoveMatcher;

    // The safe queue.
    private volatile Work mAsyncQueueHead;
    private volatile Work mAsyncQueueTail;

    /**
     * 线程安全的 Work 缓存
     */
    private volatile Work mAsyncWorkRecycles;

    private Pools.Pool<WakeSign> mWakeSignPool = new Pools.SynchronizedPool<>(24);

    private static boolean mDebug = true;

    /**
     * 默认的未捕捉异常的处理
     */
    private static Thread.UncaughtExceptionHandler sDefaultUncaughtExceptionHandler =
            (t, e) -> e.printStackTrace();

    /**
     * 用于线程同步
     */
    private final class WakeSign {
        volatile boolean waked = false;
        volatile boolean done = false;

        void recycle() {
            waked = false;
            done = false;

            mWakeSignPool.release(this);
        }
    }

    /**
     * 包含一个可以执行的 LoopEvent 及调度相关的信息
     */
    private final static class Work implements Runnable {

        /**
         * 事件类型
         */
        volatile int eventType;
        /**
         * 事件
         */
        volatile LoopEvent event;

        // 参数

        volatile Object arg1;
        volatile Object arg2;
        volatile Object arg3;
        volatile Object arg4;
        volatile Object arg5;

        /**
         * 延迟的时间的触发时间, 基于时基 {@link System#currentTimeMillis()}
         */
        volatile long deadline;

        /**
         * 队列使用
         */
        volatile Work next;

        /**
         * 如果不为 null 则用于等待时间完成
         */
        volatile WakeSign wakeSign;

        /**
         * 清楚有关变量
         */
        void clear() {
            event = null;
            arg1 = null;
            arg2 = null;
            arg3 = null;
            arg4 = null;
            arg5 = null;

            deadline = 0;

            wakeSign = null;

            next = null;
        }

        @Override
        public void run() {
            switch(eventType) {
            case EVENT_VOID :
                ((LoopEventV) event).work();
                break;
            case EVENT_1_ARG :
                // noinspection unchecked
                ((LoopEvent1Arg) event).work(arg1);
                break;
            case EVENT_2_ARG :
                // noinspection unchecked
                ((LoopEvent2Arg) event).work(arg1, arg2);
                break;
            case EVENT_3_ARG :
                // noinspection unchecked
                ((LoopEvent3Arg) event).work(arg1, arg2, arg3);
                break;
            case EVENT_4_ARG :
                // noinspection unchecked
                ((LoopEvent4Arg) event).work(arg1, arg2, arg3, arg4);
                break;
            case EVENT_5_ARG :
                // noinspection unchecked
                ((LoopEvent5Arg) event).work(arg1, arg2, arg3, arg4, arg5);
                break;
            default :
                throw new IllegalStateException();
            }
        }
    }

    /**
     * 提供一个线程用
     */
    public interface ThreadProvider {
        Thread provide(Runnable target);
    }

    @Deprecated
    public interface BeforeLoopCallback {
        void beforeLoop();
    }

    /**
     * 生成默认的线程名称
     */
    private synchronized static String defaultThreadName() {
        return "Thread For Loop Queue " + sThreadIndex++;
    }

    public static void setDebug(boolean debug) {
        mDebug = debug;
    }

    /**
     * 返回当前线程对应的 LoopQueue，如果没有对应则 返回 null
     */
    public static LoopQueue self() {
        return sLocalInstance.get();
    }

    /**
     * 默认构造
     */
    public LoopQueue() {
        this(target -> new Thread(target, defaultThreadName()));
    }

    /**
     * 通过 {@link ThreadProvider} 构造
     *
     * @param provider 提供线程用的
     */
    public LoopQueue(@Nonnull ThreadProvider provider) {
        this(provider, null);
    }

    public LoopQueue(@Nonnull ThreadProvider provider,
                     @Nullable BeforeLoopCallback beforeLoopCallback) {
        this(provider, beforeLoopCallback, sDefaultUncaughtExceptionHandler);
    }

    public LoopQueue(@Nonnull ThreadProvider provider,
                     @Nullable BeforeLoopCallback beforeLoopCallback,
                     @Nonnull Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
        mBeforeLoopCallback = beforeLoopCallback;
        mThread = provider.provide(this::loop);
        mThread.setUncaughtExceptionHandler(uncaughtExceptionHandler);
    }

    /**
     * 返回背后的线程
     */
    public @Nonnull Thread getThread() {
        return mThread;
    }

    public void waitStarted() {
        synchronized(mLock) {
            while(STATE_INIT == mState) {
                try {
                    mLock.wait();
                } catch(InterruptedException e) { /* Ignore */ }
            }
        }
    }

    /**
     * 这个方法只能在本线程调用，执行一个事件，然后返回 true. 如果 LoopThread 被
     * 关闭则会返回 false.
     *
     * @return true 如果执行了一个事件，否则 false.
     */
    public boolean loopOnce() {
        boolean looping = true;

        // check delay queue
        if(null != mDelayQueueHead) {
            long now = System.currentTimeMillis();

            // 检索已经到达的 delay work
            while(now >= mDelayQueueHead.deadline) {
                Work w = mDelayQueueHead;
                mDelayQueueHead = w.next;
                // 移到 immdediate queue.

                w.next = null;
                if(null != mQueueHead) {
                    mQueueTail.next = w;
                } else {
                    mQueueHead = w;
                }
                mQueueTail = w;
                if(null == mDelayQueueHead) {
                    break;
                }
            }
        }

        // 粗略检查 async queue 和 async remove
        if(null != mAsyncQueueHead || null != mRemoveMatcher || null == mQueueHead) {

            synchronized(mLock) {
                Work head = mAsyncQueueHead;
                if(null != head) {
                    int n = 0;

                    Work matcher = mRemoveMatcher;
                    if(null != matcher) {
                        do {
                            Work w = matcher;
                            matcher = w.next;
                            remove(w.event);

                            //noinspection SynchronizeOnNonFinalField
                            synchronized(w.wakeSign) {
                                w.wakeSign.waked = true;
                                w.wakeSign.done = true;
                                w.wakeSign.notify();
                            }

                            w.clear();
                            w.next = mAsyncWorkRecycles;
                            mAsyncWorkRecycles = w;
                        } while(null != matcher);
                        mRemoveMatcher = null;
                    }

                    // 查找 没有delay 的 work
                    while(null != head && head.deadline <= 0) {
                        Work w = head;
                        head = w.next;
                        w.next = null;
                        if(null != mQueueHead) {
                            mQueueTail.next = w;
                        } else {
                            mQueueHead = w;
                        }
                        mQueueTail = w;
                        n++;
                    }

                    // 有 delay 的 work 放入 delay queue.
                    while(null != head) {
                        Work w = head;
                        head = w.next;
                        insertDelay(w);
                        n++;
                    }

                    mAsyncQueueHead = null;

                    if(null != mWorkRecycles) {
                        // 归还 n 个 recycle work 到 async works, 不够有多少还多少
                        Work recycles = mWorkRecycles;
                        for(int i = 1; i < n && recycles.next != null; i++) {
                            recycles = recycles.next;
                        }

                        Work h = mWorkRecycles;
                        mWorkRecycles = recycles.next;
                        recycles.next = mAsyncWorkRecycles;
                        mAsyncWorkRecycles = h;
                    }
                }

                if(null == mQueueHead) {
                    if(mState == STATE_SHUTTING) {
                        looping = false;
                        if(null != mDelayQueueHead) {
                            do {
                                Work w = mDelayQueueHead;
                                mDelayQueueHead = w.next;

                                w.clear();
                                w.next = mWorkRecycles;
                                mWorkRecycles = w;
                            } while(null != mDelayQueueHead);
                        }

                        mDelayQueueTail = null;
                    } else {
                        mIsWaiting = true;
                        if(null != mDelayQueueHead) {
                            try {
                                long waitDuration = mDelayQueueHead.deadline - System.currentTimeMillis();
                                if(waitDuration > 0) {
                                    mLock.wait(waitDuration);
                                }
                            } catch(InterruptedException e) { /* Ignore */ }
                        } else {
                            try {
                                mLock.wait();
                            } catch(InterruptedException e) { /* Ignore */ }
                        }
                        mIsWaiting = false;
                    }
                }
            }
        }

        // 看 immediate queue 是否为空, 不为空则执行1次。
        if(null != mQueueHead) {
            Work work = mQueueHead;
            mQueueHead = mQueueHead.next;
            // 执行work
            try {
                work.run();
            } catch(Exception e) {
                e.printStackTrace();

                // 异常发到线程的 UncaughtExceptionHandler 处理
                Thread.currentThread().getUncaughtExceptionHandler()
                        .uncaughtException(Thread.currentThread(), e);
            }
            if(null != work.wakeSign) {
                //noinspection SynchronizeOnNonFinalField
                synchronized(work.wakeSign) {
                    work.wakeSign.waked = true;
                    work.wakeSign.done = true;
                    work.wakeSign.notify();
                }
            }
            work.clear();
            work.next = mWorkRecycles;
            mWorkRecycles = work;
        }

        return looping;
    }

    /**
     * 请求结束这个 LoopThread. 不会马上退出，而是执行完队列中剩余的shi=再结束.
     * 而这个方法会立即返回. 可以使用 {@link #joinQuit()} 等待线程结束.
     *
     * @return true 如果成功请求退出, false 如果线程没有启动或者已经请求退出或者已经退出.
     */
    public boolean requestQuit() {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            mState = STATE_SHUTTING;
            if(mIsWaiting) {
                mLock.notifyAll();
            }
        }

        return true;
    }

    /**
     * 等待处理完所有事件后结束.
     */
    public void joinQuit() throws InterruptedException {
        synchronized(mLock) {
            while(true) {
                int state = mState;

                switch(state) {
                case STATE_LOOPING:
                    throw new IllegalStateException("Loop Queue is still running.");
                case STATE_SHUTTING:
                    mLock.wait();
                    break;
                case STATE_INIT :
                case STATE_STOPPED :
                    return;
                default :
                    throw new IllegalStateException();
                }
            }
        }
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean post(@Nonnull LoopEventV event) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_VOID;
            w.event = event;

            postInner(0, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean post(@Nonnull LoopEvent1Arg<T> event, T arg) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_1_ARG;
            w.event = event;

            w.arg1 = arg;

            postInner(0, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean post(@Nonnull LoopEvent2Arg<T1, T2> event, T1 arg1, T2 arg2) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_2_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;

            postInner(0, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean post(@Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                     T1 arg1, T2 arg2, T3 arg3) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_3_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;

            postInner(0, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean post(@Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                         T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_4_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;

            postInner(0, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean post(@Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                             T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_5_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;
            w.arg5 = arg5;

            postInner(0, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean postUnsafe(@Nonnull LoopEventV event) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_VOID;
        w.event = event;

        postUnsafeInner(0, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean postUnsafe(@Nonnull LoopEvent1Arg<T> event, T arg) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_1_ARG;
        w.event = event;

        w.arg1 = arg;

        postUnsafeInner(0, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean postUnsafe(@Nonnull LoopEvent2Arg<T1, T2> event, T1 arg1, T2 arg2) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_2_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;

        postUnsafeInner(0, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean postUnsafe(@Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                           T1 arg1, T2 arg2, T3 arg3) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_3_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;

        postUnsafeInner(0, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean postUnsafe(@Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                               T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_4_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;
        w.arg4 = arg4;

        postUnsafeInner(0, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean postUnsafe(@Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                                   T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_5_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;
        w.arg4 = arg4;
        w.arg5 = arg5;

        postUnsafeInner(0, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程安全的.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 post 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean postDelay(long millis, @Nonnull LoopEventV event) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_VOID;
            w.event = event;

            postInner(millis, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程安全的.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 post 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean postDelay(long millis, @Nonnull LoopEvent1Arg<T> event, T arg) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_1_ARG;
            w.event = event;

            w.arg1 = arg;

            postInner(millis, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程安全的.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 post 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean postDelay(long millis, @Nonnull LoopEvent2Arg<T1, T2> event,
                                      T1 arg1, T2 arg2) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_2_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;

            postInner(millis, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程安全的.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 post 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean postDelay(long millis, @Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                          T1 arg1, T2 arg2, T3 arg3) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_3_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;

            postInner(millis, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程安全的.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 post 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean postDelay(long millis, @Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                              T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_4_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;

            postInner(millis, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程安全的.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 post 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean postDelay(long millis, @Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                                  T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_5_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;
            w.arg5 = arg5;

            postInner(millis, false, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 postUnsafe 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean postDelayUnsafe(long millis, @Nonnull LoopEventV event) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_VOID;
        w.event = event;

        postUnsafeInner(millis, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 postUnsafe 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean postDelayUnsafe(long millis, @Nonnull LoopEvent1Arg<T> event, T arg) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_1_ARG;
        w.event = event;

        w.arg1 = arg;

        postUnsafeInner(millis, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 postUnsafe 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean postDelayUnsafe(long millis, @Nonnull LoopEvent2Arg<T1, T2> event,
                                            T1 arg1, T2 arg2) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_2_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;

        postUnsafeInner(millis, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 postUnsafe 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean postDelayUnsafe(long millis, @Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                                T1 arg1, T2 arg2, T3 arg3) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_3_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;

        postUnsafeInner(millis, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 postUnsafe 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean postDelayUnsafe(long millis, @Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                                    T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_4_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;
        w.arg4 = arg4;

        postUnsafeInner(millis, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个有延时的事件，线程不安全的，只能本线程调用.
     * <p/>
     *
     * @param millis 延迟执行的时间, 单位 milliseconds， 传 0 等于 postUnsafe 系列方法
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean postDelayUnsafe(long millis, @Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                                        T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_5_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;
        w.arg4 = arg4;
        w.arg5 = arg5;

        postUnsafeInner(millis, false, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public final boolean postAtTime(long timeInMillis, @Nonnull LoopEventV event) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_VOID;
            w.event = event;

            postInner(timeInMillis, true, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean postAtTime(long timeInMillis, @Nonnull LoopEvent1Arg<T> event, T arg) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_1_ARG;
            w.event = event;

            w.arg1 = arg;

            postInner(timeInMillis, true, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean postAtTime(long timeInMillis, @Nonnull LoopEvent2Arg<T1, T2> event,
                                       T1 arg1, T2 arg2) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_2_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;

            postInner(timeInMillis, true, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean postAtTime(long timeInMillis, @Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                           T1 arg1, T2 arg2, T3 arg3) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_3_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;

            postInner(timeInMillis, true, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean postAtTime(long timeInMillis, @Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                               T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_4_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;

            postInner(timeInMillis, true, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程安全的.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean postAtTime(long timeInMillis, @Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                                   T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            Work w = obtainWork(true);

            w.eventType = EVENT_5_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;
            w.arg5 = arg5;

            postInner(timeInMillis, true, w);
        }

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean postAtTimeUnsafe(long timeInMillis, @Nonnull LoopEventV event) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_VOID;
        w.event = event;

        postUnsafeInner(timeInMillis, true, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean postAtTimeUnsafe(long timeInMillis, @Nonnull LoopEvent1Arg<T> event, T arg) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_1_ARG;
        w.event = event;

        w.arg1 = arg;

        postUnsafeInner(timeInMillis, true, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean postAtTimeUnsafe(long timeInMillis, @Nonnull LoopEvent2Arg<T1, T2> event,
                                             T1 arg1, T2 arg2) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_2_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;

        postUnsafeInner(timeInMillis, true, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean postAtTimeUnsafe(long timeInMillis, @Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                                 T1 arg1, T2 arg2, T3 arg3) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_3_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;

        postUnsafeInner(timeInMillis, true, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean postAtTimeUnsafe(long timeInMillis, @Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                                     T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_4_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;
        w.arg4 = arg4;

        postUnsafeInner(timeInMillis, true, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个指定事件发生的事件，基于时基 {@link System#currentTimeMillis()}，
     * 线程不安全的，只能本线程调用.
     * <p/>
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean postAtTimeUnsafe(long timeInMillis, @Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                                         T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        Work w = obtainWork(false);

        w.eventType = EVENT_5_ARG;
        w.event = event;

        w.arg1 = arg1;
        w.arg2 = arg2;
        w.arg3 = arg3;
        w.arg4 = arg4;
        w.arg5 = arg5;

        postUnsafeInner(timeInMillis, true, w);

        return true;
    }

    /**
     * 在 LoopQueue 中添加一个事件，并等待事件执行完成后再返回
     * <p/>
     *
     * 这个方法不能再本线程调用，否则会锁死.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public final boolean postWait(@Nonnull LoopEventV event) {
        Work w;
        WakeSign wakeSign = obtainWakeSign();

        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            w = obtainWork(true);

            w.eventType = EVENT_VOID;
            w.event = event;

            w.wakeSign = wakeSign;

            postInner(0, false, w);
        }

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized(wakeSign) {
            while(!wakeSign.waked) {
                try {
                    wakeSign.wait();
                } catch(InterruptedException e) { /* Loop */ }
            }
        }

        boolean done = wakeSign.done;
        wakeSign.recycle();

        return done;
    }

    /**
     * 在 LoopQueue 中添加一个事件，并等待事件执行完成后再返回
     * <p/>
     *
     * 这个方法不能再本线程调用，否则会锁死.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T> boolean postWait(@Nonnull LoopEvent1Arg<T> event, T arg) {
        Work w;
        WakeSign wakeSign = obtainWakeSign();

        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            w = obtainWork(true);

            w.eventType = EVENT_1_ARG;
            w.event = event;

            w.arg1 = arg;

            w.wakeSign = wakeSign;

            postInner(0, false, w);
        }

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized(wakeSign) {
            while(!wakeSign.waked) {
                try {
                    wakeSign.wait();
                } catch(InterruptedException e) { /* Loop */ }
            }
        }

        boolean done = wakeSign.done;
        wakeSign.recycle();

        return done;
    }

    /**
     * 在 LoopQueue 中添加一个事件，并等待事件执行完成后再返回
     * <p/>
     *
     * 这个方法不能再本线程调用，否则会锁死.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2> boolean postWait(@Nonnull LoopEvent2Arg<T1, T2> event,
                                     T1 arg1, T2 arg2) {
        Work w;
        WakeSign wakeSign = obtainWakeSign();

        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            w = obtainWork(true);

            w.eventType = EVENT_2_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;

            w.wakeSign = wakeSign;

            postInner(0, false, w);
        }

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized(wakeSign) {
            while(!wakeSign.waked) {
                try {
                    wakeSign.wait();
                } catch(InterruptedException e) { /* Loop */ }
            }
        }

        boolean done = wakeSign.done;
        wakeSign.recycle();

        return done;
    }

    /**
     * 在 LoopQueue 中添加一个事件，并等待事件执行完成后再返回
     * <p/>
     *
     * 这个方法不能再本线程调用，否则会锁死.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3> boolean postWait(@Nonnull LoopEvent3Arg<T1, T2, T3> event,
                                         T1 arg1, T2 arg2, T3 arg3) {
        Work w;
        WakeSign wakeSign = obtainWakeSign();

        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            w = obtainWork(true);

            w.eventType = EVENT_3_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;

            w.wakeSign = wakeSign;

            postInner(0, false, w);
        }

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized(wakeSign) {
            while(!wakeSign.waked) {
                try {
                    wakeSign.wait();
                } catch(InterruptedException e) { /* Loop */ }
            }
        }

        boolean done = wakeSign.done;
        wakeSign.recycle();

        return done;
    }

    /**
     * 在 LoopQueue 中添加一个事件，并等待事件执行完成后再返回
     * <p/>
     *
     * 这个方法不能再本线程调用，否则会锁死.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4> boolean postWait(@Nonnull LoopEvent4Arg<T1, T2, T3, T4> event,
                                             T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
        Work w;
        WakeSign wakeSign = obtainWakeSign();

        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            w = obtainWork(true);

            w.eventType = EVENT_4_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;

            w.wakeSign = wakeSign;

            postInner(0, false, w);
        }

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized(wakeSign) {
            while(!wakeSign.waked) {
                try {
                    wakeSign.wait();
                } catch(InterruptedException e) { /* Loop */ }
            }
        }

        boolean done = wakeSign.done;
        wakeSign.recycle();

        return done;
    }

    /**
     * 在 LoopQueue 中添加一个事件，并等待事件执行完成后再返回
     * <p/>
     *
     * 这个方法不能再本线程调用，否则会锁死.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public <T1, T2, T3, T4, T5> boolean postWait(@Nonnull LoopEvent5Arg<T1, T2, T3, T4, T5> event,
                                                 T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) {
        Work w;
        WakeSign wakeSign = obtainWakeSign();

        synchronized(mLock) {
            if(STATE_LOOPING != mState) {
                return false;
            }

            w = obtainWork(true);

            w.eventType = EVENT_5_ARG;
            w.event = event;

            w.arg1 = arg1;
            w.arg2 = arg2;
            w.arg3 = arg3;
            w.arg4 = arg4;
            w.arg5 = arg5;

            w.wakeSign = wakeSign;

            postInner(0, false, w);
        }

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized(wakeSign) {
            while(!wakeSign.waked) {
                try {
                    wakeSign.wait();
                } catch(InterruptedException e) { /* Loop */ }
            }
        }

        boolean done = wakeSign.done;
        wakeSign.recycle();

        return done;
    }

    /**
     * post 方法实现
     */
    private void postInner(long time, boolean isTimeAbsolute, @Nonnull Work w) {
        if(mDebug) {
            if(this == LoopQueue.self()) {
                System.out.println("Use postUnsafe instead of post in current thread ...");
            }
        }

        if(time <= 0) {
            // 没 delay
            Work head = mAsyncQueueHead;

            if(null == head) {
                mAsyncQueueHead = w;
                mAsyncQueueTail = w;
            } else {
                while(null != head.next && 0 >= head.next.deadline) {
                    head = head.next;
                }
                if(null != head.next)
                    w.next = head.next;
                else {
                    w.next = null;
                    mAsyncQueueTail = w;
                }
                head.next = w;
            }
        } else {
            // 有delay， 计算deadline.
            w.deadline = isTimeAbsolute ? time : System.currentTimeMillis() + time;

            // 放进 async queue. deadline 为0的将会直接拿到immediate queue，不为0的拿到delay queue.
            Work head = mAsyncQueueHead;
            if(null == head) {
                // async queue 为空, 头和尾都指向它.
                mAsyncQueueTail = w;
                mAsyncQueueHead = w;
            } else {
                // async queue 不为空, 插入
                Work tail = mAsyncQueueTail;
                if(w.deadline >= tail.deadline) {
                    // deadline 大于等于 队列尾的deadline, 直接放最后.
                    tail.next = w;
                    mAsyncQueueTail = w;
                } else if(w.deadline < head.deadline) {
                    // deadline 小于队列头的deadline. 直接放队列头.
                    w.next = head;
                    mAsyncQueueHead = w;
                } else {
                    // 插入
                    Work last = head, the;
                    while(true) {
                        the = last.next;
                        if(w.deadline < the.deadline)
                            break;
                        last = the;
                    }
                    last.next = w;
                    w.next = the;
                }
            }
        }

        if(mIsWaiting) {
            mLock.notifyAll();
        }
    }

    private boolean postUnsafeInner(long time, boolean isTimeAbsolute, @Nonnull Work work) {
        if(mDebug) {
            if(this != LoopQueue.self()) {
                throw new IllegalStateException("Do not use postUnsafe in another thread !!!");
            }
        }

        if(STATE_LOOPING != mState) {
            return false;
        }

        if(time > 0) {
            // 有时间设置

            work.deadline = isTimeAbsolute ? time : time + System.currentTimeMillis();
            insertDelay(work);
        } else {
            // 不需要延迟，放 immediate queue.

            work.next = null;
            if(null != mQueueHead) {
                mQueueTail.next = work;
            } else {
                mQueueHead = work;
            }
            mQueueTail = work;
        }

        return true;
    }

    private void insertDelay(Work work) {
        if(null == mDelayQueueHead) {
            // delay queue 为空， 头和尾都指向它.
            mDelayQueueTail = work;
            work.next = null;
            mDelayQueueHead = work;
        } else {
            // delay queue 不为空.
            if(work.deadline >= mDelayQueueTail.deadline) {
                // deadline 大于等于队列尾的 deadline, 直接放最后.
                mDelayQueueTail.next = work;
                work.next = null;
                mDelayQueueTail = work;
            } else if(work.deadline < mDelayQueueHead.deadline) {
                // deadline 小于队列头的 deadline. 直接放队列头.
                work.next = mDelayQueueHead;
                mDelayQueueHead = work;
            } else {
                // 插入
                Work last = mDelayQueueHead;
                Work the;
                while(true) {
                    the = last.next;
                    if(work.deadline < the.deadline)
                        break;
                    last = the;
                }
                last.next = work;
                work.next = the;
            }
        }
    }

    /**
     * 移除添加的某个事件， 多次添加同一个的会全部移除，线程安全的.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean remove(@Nonnull LoopEvent event) {
        if(this == self()) {
            if(!removeUnsafe(event)) {
                return false;
            }
            synchronized(mLock) {
                removeWorks(QUEUE_ASYNC, event);
            }

            return true;
        } else {
            return postWait(this::remove, event);
        }
    }

    /**
     * 移除添加的某个事件， 多次添加同一个的会全部移除，线程不安全的，只能本线程调用.
     * 注意这个方法无法移除在异步队列中的事件，所以仅在确认某事件在本线程下添加时才可以
     * 用这个方法移除.
     *
     * @return true 如果成功， 否则为 LoopQueue 正在关闭或已关闭或未启动导致失败
     */
    @Override
    public boolean removeUnsafe(LoopEvent event) {
        if(STATE_LOOPING != mState) {
            return false;
        }

        removeWorks(QUEUE_IMMEDIATE, event);
        removeWorks(QUEUE_DELAY, event);

        return true;
    }

    /**
     * 移除某队列中某事件对应的 Work(s)
     */
    private void removeWorks(int queue, LoopEvent loopEvent) {
        Work head, tail, recycle;

        switch(queue) {
        case QUEUE_IMMEDIATE :
            head = mQueueHead;
            tail = mQueueTail;
            recycle = mWorkRecycles;
            break;
        case QUEUE_DELAY :
            head = mDelayQueueHead;
            tail = mDelayQueueTail;
            recycle = mWorkRecycles;
            break;
        case QUEUE_ASYNC :
            head = mAsyncQueueHead;
            tail = mAsyncQueueTail;
            recycle = mAsyncWorkRecycles;
            break;
        default :
            throw new IllegalArgumentException();
        }

        if(null != head) {
            // 先不管第一个.
            Work last = head, w = head.next;
            while(null != w) {
                if(w.event == loopEvent) {
                    if(null != w.wakeSign) {
                        // noinspection SynchronizeOnNonFinalField
                        synchronized(w.wakeSign) {
                            w.wakeSign.waked = true;
                            w.wakeSign.notify();
                        }
                    }

                    last.next = w.next;
                    w.clear();
                    w.next = recycle;
                    recycle = w;
                    w = last.next;
                } else {
                    last = w;
                    w = w.next;
                }
            }
            // 尾可能已改变
            tail = last;

            // 再看第一个
            w = head;
            if(w.event == loopEvent) {
                head = w.next;
                if(null != w.wakeSign) {
                    // noinspection SynchronizeOnNonFinalField
                    synchronized(w.wakeSign) {
                        w.wakeSign.waked = true;
                        w.wakeSign.notify();
                    }
                }

                w.clear();
                w.next = recycle;
                recycle = w;
            }
        }

        switch(queue) {
        case QUEUE_IMMEDIATE :
            mQueueHead = head;
            mQueueTail = tail;
            mWorkRecycles = recycle;
            break;
        case QUEUE_DELAY :
            mDelayQueueHead = head;
            mDelayQueueTail = tail;
            mWorkRecycles = recycle;
            break;
        case QUEUE_ASYNC :
            mAsyncQueueHead = head;
            mAsyncQueueTail = tail;
            mAsyncWorkRecycles = recycle;
            break;
        }
    }

    /**
     * 获取一个 Work 对象
     *
     * @param fromSave 如果为 true 则尝试从 {@link #mAsyncWorkRecycles} 获取
     *                 否则尝试从 {@link #mWorkRecycles} 获取
     */
    private @Nonnull
    Work obtainWork(boolean fromSave) {
        Work w;

        if(fromSave) {
            w = mAsyncWorkRecycles;
            if(w != null) {
                mAsyncWorkRecycles = w.next;
                w.next = null;
            }
        } else {
            w = mWorkRecycles;
            if(w != null) {
                mWorkRecycles = w.next;
                w.next = null;
            }
        }

        if(mDebug) {
            if(w != null) {
                if(null != w.event) {
                    throw new RuntimeException();
                }
            }
        }

        return null == w ? new Work() : w;
    }

    private WakeSign obtainWakeSign() {
        WakeSign wakeSign = mWakeSignPool.acquire();
        if(null == wakeSign) {
            wakeSign = new WakeSign();
        }

        return wakeSign;
    }

    public void prepareLoop() {
        if(mThread != Thread.currentThread()) {
            throw new IllegalStateException("Only the working thread could invoke 'prepareLoop()'.");
        }

        synchronized(mLock) {
            if(STATE_INIT != mState) {
                return;
            }

            sLocalInstance.set(this);

            mState = STATE_LOOPING;
            mLock.notifyAll();
        }

        if(null != mBeforeLoopCallback) {
            mBeforeLoopCallback.beforeLoop();
        }
    }

    /**
     * 背后的线程执行的工作
     */
    public void loop() {
        // 绑定实例到线程本地
        prepareLoop();

        //noinspection StatementWithEmptyBody
        while(loopOnce());

        synchronized(mLock) {
            mState = STATE_STOPPED;
            mLock.notifyAll();
        }

        sLocalInstance.remove();
    }
}

